#include "tim.h"

uint16_t tim6_ms_fac = 0;  // 毫秒因子
uint16_t tim6_us_fac = 0;  // 微秒因子

/**
 * 简述：TIM6 初始化
 * 参数：prescaler 预分频
 * 返回值：无
 **/
void tim6_init(uint32_t prescaler)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	
	// 使能 TIM6 时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	
	// 配置时基单元
	//TIM_TimeBaseInitStruct.TIM_ClockDivision = ;  // 基本定时器没有
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;  // TIM6 和 TIM7 只支持向上计数
	TIM_TimeBaseInitStruct.TIM_Period      = 0;  // 周期
	TIM_TimeBaseInitStruct.TIM_Prescaler   = prescaler - 1;
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;  // TIM1 和 TIM8 才用
	//void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStruct);
	
	// 禁用定时器
	// void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
	TIM_Cmd(TIM6, DISABLE);

	tim6_ms_fac = 72000 / prescaler;
	tim6_us_fac = 72 / prescaler;
}

/**
 * 简述：TIM6 毫秒延时
 * 参数：ms 延时的毫秒数
 * 返回值：无
 **/
void tim6_delay_ms(uint32_t ms)
{
	int count = ms * tim6_ms_fac / 0xFFFF;  // 以最大值延时的次数
	uint16_t remain = ms * tim6_ms_fac % 0xFFFF;  // 剩余计数值
	
	if (count) {
		TIM6->ARR = 0xFFFF;
		TIM6->CNT = 0;
		TIM_Cmd(TIM6, ENABLE);
		while (count--) {
			// 等待更新标志
			// FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
			while (TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);
			// 清除更新标志
			// void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
			TIM_ClearFlag(TIM6, TIM_FLAG_Update);
		}
		TIM_Cmd(TIM6, DISABLE);
	}
	if (remain) {
		TIM6->ARR = remain;
		TIM6->CNT = 0;
		TIM_Cmd(TIM6, ENABLE);
		while (TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);
		TIM_ClearFlag(TIM6, TIM_FLAG_Update);
		TIM_Cmd(TIM6, DISABLE);
	}
}

/**
 * 简述：TIM6 微秒延时。不考虑溢出情况
 * 参数：us 延时的微秒数
 * 返回值：无
 **/
void tim6_delay_us(uint32_t us)
{
	TIM6->ARR = us * tim6_us_fac;
	TIM6->CNT = 0;
	TIM_Cmd(TIM6, ENABLE);
	while (TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);
	TIM_ClearFlag(TIM6, TIM_FLAG_Update);
	TIM_Cmd(TIM6, DISABLE);
}

//-------------------------------------------------------------------

/**
 * 简述：TIM6 初始化
 * 参数：prescaler 预分频
 *       period    周期
 * 返回值：无
 **/
void tim3_ch3_ledr_init(uint32_t prescaler, uint32_t period)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	// 使能 GPIOC 和 AFIO 时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
	
	// 使能 TIM3 时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	// 重映射 TIM3_CH3 到 PC1
	GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);
	
	// 配置 PC8 为复用功能推挽输出
	GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStruct);
	
	// 初始化 TIM3 时基单元
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV4;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数
	TIM_TimeBaseInitStruct.TIM_Period      = period;  // 周期
	TIM_TimeBaseInitStruct.TIM_Prescaler   = prescaler - 1;
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;  // TIM1 和 TIM8 才用
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
	
	// 初始化 TIM3_CH3 输出比较通道
	// TIM_OCInitStruct.TIM_OCIdleState = ;   // 这 4 个成员高级定时器才用
	// TIM_OCInitStruct.TIM_OCNIdleState = ;
	// TIM_OCInitStruct.TIM_OCNPolarity = ;
	// TIM_OCInitStruct.TIM_OutputNState = ;
	TIM_OCInitStruct.TIM_OCMode      = TIM_OCMode_PWM2;
	TIM_OCInitStruct.TIM_OCPolarity  = TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse       = 0;  // 比较值，在应用中设置
	// void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
	TIM_OC3Init(TIM3, &TIM_OCInitStruct);
	
	// 使能 TIM3
	TIM_Cmd(TIM3, ENABLE);
}
